package model

import (
	"errors"

	"github.com/quarkcloudio/quark-go/v2/pkg/dal/db"
	sqlManager "github.com/wsl/hi-go/plugins/sql"
	"github.com/wsl/hi-go/types"
	"gorm.io/gorm"
)

type User struct {
	Id        int              `json:"id" gorm:"autoIncrement"`
	Name      string           `json:"name"`
	Password  string           `json:"-"`
	Status    int              `json:"status" gorm:"default:1"`
	CreatedAt *types.LocalTime `json:"created_at"`
	UpdatedAt *types.LocalTime `json:"updated_at"`
	DeletedAt gorm.DeletedAt   `json:"-"`
}

func (p *User) Create(username string, password string) error {
	user := User{Name: username, Password: password}
	dbErr := db.Client.Model(&p).Create(&user).Error
	return dbErr
}

func (p *User) Query(username string) (user User, err error) {
	tx := db.Client.Begin()
	query := tx.Model(&p)
	err = query.Where("name = ?", username).First(&user).Set("gorm:query_option", "for update").Error
	if err != nil {
		tx.Rollback()
		return user, err
	}
	tx.Commit()
	return user, err
}

func (p *User) Index(page int, pageSize int) (sqlManager.AutoList[*User], error) {
	var users []*User
	// Scopes 公用代码块
	query := db.Client.Model(&p)
	var count int64 = 0
	// 获取总数
	if totalErr := query.Count(&count).Error; totalErr != nil {
		return sqlManager.AutoList[*User]{List: users, Total: count}, totalErr
	}
	err := query.Scopes(sqlManager.PageManager(page, pageSize)).Unscoped().Find(&users).Error
	return sqlManager.AutoList[*User]{List: users, Total: count}, err
}

func (p *User) Delete(userId int) error {
	query := db.Client.Model(&p)
	err := query.Where("id = ?", userId).Delete(&p).Error
	return err
}

func (p *User) Update(param types.UpdateParam) error {
	query := db.Client.Model(&p)
	var user User
	// 检查用户是否存在且未被删除
	if err := query.Where("id = ?", param.Id).First(&user).Error; err != nil {
		return errors.New("用户不存在")
	}
	if _, err := p.Query(param.Name); err == nil {
		return errors.New("用户名已存在")
	}
	err := query.Where("id = ?", param.Id).Updates(&param).Error
	return err
}

func (p *User) Detail(userId int) (User, error) {
	var user User
	query := db.Client.Model(&p)
	err := query.Where("id = ?", userId).First(&user).Error
	return user, err
}
